package com.bac.rentmap.ad.crawler.stepped.predicate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import com.bac.rentmap.ad.crawler.CrawledAd;
import com.bac.rentmap.ad.crawler.stepped.SteppedAdCrawler;

public class PredicateSteppedAdCrawler<T extends CrawledAd> implements
		SteppedAdCrawler<T> {
	private static final Logger log = Logger.getLogger(PredicateSteppedAdCrawler.class
			.getName());
	
	public static final int DEFAULT_NON_RELEVANT_STOP_THRESHOLD = 10;
	private int nonRelevantStopThreshold = DEFAULT_NON_RELEVANT_STOP_THRESHOLD;
	private RelevancePredicate<T> relevancePredicate;
	private SteppedAdCrawler<T> steppedAdCrawler;
	private int nonRelevantCount;

	public PredicateSteppedAdCrawler(SteppedAdCrawler<T> steppedAdCrawler,
			RelevancePredicate<T> relevancePredicate) {
		this.steppedAdCrawler = steppedAdCrawler;
		this.relevancePredicate = relevancePredicate;
	}

	public List<T> crawlNext() throws IOException {
		if (nonRelevantCount >= nonRelevantStopThreshold)
			return null;
		List<T> crawledAds = steppedAdCrawler.crawlNext();
		List<T> res = filterRelevant(crawledAds);
		log.info(res.size() + "/" + crawledAds.size() + " crawled ads are relevant");
		return res;
	}

	private List<T> filterRelevant(List<T> crawledAds) {
		List<T> res = new ArrayList<T>();
		for (T crawledAd : crawledAds) {
			if (relevancePredicate.isRelevant(crawledAd)) {
				res.add(crawledAd);
			} else {
				if (++nonRelevantCount >= nonRelevantStopThreshold)
					break;
			}
		}
		return res;
	}

	public void setNonRelevantStopThreshold(int nonRelevantStopThreshold) {
		this.nonRelevantStopThreshold = nonRelevantStopThreshold;
	}
}
